<?php


namespace app\home\controller;


use app\base\BaseController;
use PhpOffice\PhpSpreadsheet\IOFactory;
use think\Exception;
use think\facade\Db;
use think\facade\View;

class PayOrder extends BaseController
{
    protected $table='receipt_order';
    protected $title='付款单';
    private $sessionKey='pagePayOrder';
    /**
     * date:2024/3/21
     * 列表
     */
    public function index()
    {
        $param=$this->param;
        if (request()->isAjax()) {

            $where[]=['i.status','>',-1];
            $where[]=['i.r_type','=',1];
            foreach (['p_code','p_name','i_status','i_orderNum'] as $i){
                if (isset($param[$i])&&$param[$i]){
                    $k=str_replace('_','.',$i);
                    $where[]=[$k,'=',$param[$i]];
                }
            }

            if (isset($param['orderDate'])&&$param['orderDate']){
                $times=explode('~',$param['orderDate']);
                $where[]=['i.orderDate','between',$times];
            }
            session($this->sessionKey,$where);
            $rows = empty($param['limit']) ? get_config('app.page_size') : $param['limit'];
            $list = Db::name($this->table)->alias('i')
                ->join('purveyor p','p.id=i.punter_id','left')
                ->join('admin a','a.id=i.checkUser','left')
                ->where($where)
                ->field('i.*,p.name as pName,a.name as username')
                ->paginate($rows);
            return table_assign(0, '', $list);
        } else {

            return view();
        }

    }

    /**
     * @return \json|\think\response\View
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     * date:2024/3/21
     * 添加
     */
    public function add()
    {
        $param = get_params();
        if (request()->isAjax()) {
            $postData=$this->param;
            $mxid=$postData['mxid']??[];
            $punter_id=$postData['punter_id'];
            $sale_reconcile_id=$postData['sale_reconcile_id']??[];
            $money=$postData['money']??[];
            $oldNum=$postData['oldNum']??[];
            $paymentPrice=0;
            if (!$sale_reconcile_id||!$money){
                return to_assign(1,'参数缺失');
            }
            if ($oldNum){
                foreach ($oldNum as $k=>$o){
                    if ($money[$k]>$oldNum[$k]){
                        return to_assign(1,'收款金额大于回款金额');
                        break;
                    }
                }
            }
            foreach ($money as $m){
                $paymentPrice+=$m;
            }
            $param=[
                'orderDate'=>$postData['orderDate'],
                'status'=>$postData['status'],
                'punter_id'=>$postData['punter_id'],
                'id'=>$postData['id']??0,
            ];

            Db::startTrans();
            $param['update_time']=time();
            $id=$param['id']??0;
            try {
                $param['paymentPrice']=$paymentPrice;
                if ($param['id'] > 0) {
                    Db::name($this->table)->strict(false)->field(true)->update($param);
                    add_log('edit', $param['id'], $postData,$this->title);
                } else {
                    $param['r_type']=1;
                    $param['orderNum']=orderNum('SFKDH');
                    $param['create_time'] = time();
                    $id = Db::name($this->table)->strict(false)->field(true)->insertGetId($param);
                    add_log('add', $id, $postData,$this->title);
                }
                foreach ($sale_reconcile_id as $k=>$v){
                    if (empty($money[$k])||empty($sale_reconcile_id[$k])){
                        throw new Exception('参数有误');
                    }
                    $mxData=[
                        'receipt_id'=>$id,
                        'punter_id'=>$punter_id,
                        'rod_type'=>1,
                        'sale_reconcile_id'=>$sale_reconcile_id[$k],
                        'money'=>$money[$k],
                        'create_time'=>time(),
                        'update_time'=>time()
                    ];
                    if (isset($mxid[$k])&&$mxid[$k]){
                        $mxData['id']=$mxid[$k];
                    }
                    Db::name('receipt_order_detail')->save($mxData);
                }
                Db::commit();
            }catch (\Exception $e){
                Db::rollback();
                return to_assign(1,'操作失败:'.$e->getMessage());
            }

            return to_assign();
        } else {
            $id = isset($param['id']) ? $param['id'] : 0;
            $detail=[];
            if ($id > 0) {
                $detail = Db::name($this->table)->where('id', $id)->field("*,(select username from fy_admin a where a.id=checkUser)username")->find();

                $mxList=Db::name('receipt_order_detail')
                    ->alias('ord')
                    ->where('ord.status','>','-1')->where('ord.receipt_id',$id)
                    ->join('sale_reconcile sr','sr.id=ord.sale_reconcile_id','left')
                    ->field("ord.*,sr.reconcilePrice,sr.orderNum as srOrderNum,(select sum(money) from fy_receipt_order_detail rod where rod.status=2 and rod.sale_reconcile_id=sr.id)recondMoney")
                    ->select()->each(function ($item,$index){
                        $item['unPrice']=$item['reconcilePrice']-$item['recondMoney'];
                        return $item;
                    });
                View::assign('mxList', $mxList);
            }
            View::assign('detail', $detail);
            $punterList=Db::name('purveyor')->where('dw_type',1)->where('status',1)->field('id,name')->select();
            View::assign('punterList',$punterList);
            View::assign('id', $id);
            View::assign('defalutTime', date('Y-m-d'));
            return \view('form');
        }
    }

    public function addMx()
    {     $punter_id=$this->param['punter_id']??'';
        if (request()->isPost()) {
            if (!$punter_id){
                return table_assign(1, '参数缺失',[]);
            }
            $where[]=['punter_id','=',$punter_id];
            $where[]=['status','=',2];
            $where[]=['is_end','=',2];
            $where[]=['s_type','=',1];
            foreach (['bar_code','mdName','specs','locatorName','warehouseName'] as $v){
                if (isset($this->param[$v])&&$this->param[$v]){
                    $where[]=[$v,'like','%'.$this->param[$v].'%'];
                }
            }
            $limit=$this->param['limit']??15;
            $list=Db::name('sale_reconcile')
                ->where($where)
                ->field("*,(select sum(money) from fy_receipt_order_detail rod where rod.status=2 and rod.sale_reconcile_id=fy_sale_reconcile.id)recondMoney")
                ->paginate($limit)->each(function ($item,$index){
                    $item['unPrice']=$item['reconcilePrice']-$item['recondMoney'];
                    return $item;
                });
            View::assign('list',$list);
            return table_assign(0, '', $list);
        } else {
            return \view('mx');
        }

    }
    public function removeMx()
    {
        $id=$this->param['id'];
        $info=Db::name('receipt_order_detail')->where('status','>',-1)->where('id',$id)->find();
        if (!$info){
            return to_assign(1,'数据不存在');
        }
        $countMone=Db::name('receipt_order_detail')->where('status','>',-1)
            ->where('receipt_id',$info['receipt_id'])
            ->where('id','<>',$id)
            ->sum('money');
        try {
            Db::name($this->table)->where('id',$info['receipt_id'])->update(['update_time'=>time(),'paymentPrice'=>$countMone]);
            Db::name('receipt_order_detail')->where('id',$id)->update(['status'=>-1,'update_time'=>time(),'deleted'=>time()]);
            add_log('add', $id, $this->param,$this->title);
        }catch (\Exception $e){
            return to_assign(1,'删除失败:'.$e->getMessage());
        }
        return to_assign();
    }

    /**
     * date:2024/4/18
     * 确认
     */
    public function onSure()
    {
        $id=$this->param['id']??0;
        if (!$id){
            return to_assign(1,'参数缺失');
        }
        $info=Db::name($this->table)->where('id',$id)->find();
        if (!$info||$info['status']!=1){
            return to_assign(1,'参数有误');
        }
        $mx= Db::name('receipt_order_detail')
            ->alias('ord')
            ->where('ord.status','>','-1')->where('ord.receipt_id',$id)
            ->join('sale_reconcile sr','sr.id=ord.sale_reconcile_id','left')
            ->field("ord.*,sr.reconcilePrice,sr.orderNum as srOrderNum,
            (select sum(money) from fy_receipt_order_detail rod where rod.status=2 and rod.sale_reconcile_id=sr.id)recondMoney,
            (select sum(money) from fy_receipt_order_detail rod where rod.status > -1 and rod.sale_reconcile_id=sr.id and rod.receipt_id=$id)bcMoney
            ")
            ->select()->each(function ($item,$index){
                $item['unPrice']=$item['reconcilePrice']-$item['recondMoney'];
                return $item;
            });
        if (!$mx){
            return to_assign(1,'请添加明细');
        }
        Db::startTrans();
        try {
            $srIds=[];
            foreach ($mx as $m){
                if ($m['unPrice']==$m['bcMoney']){
                    $srIds[]=$m['sale_reconcile_id'];
                }
                if ($m['unPrice']<$m['bcMoney']){
                    throw new Exception('收款金额大于未回款金额');
                }
            }
            Db::name($this->table)->where('id',$id)->update(['checkUser'=>$this->uid,'status'=>2,'update_time'=>time(),'checkTime'=>time()]);
            Db::name('receipt_order_detail')
                ->where('receipt_id',$id)
                ->where('status','>',-1)
                ->update(['status'=>2,'update_time'=>time()]);
            if ($srIds){
                Db::name('sale_reconcile')
                    ->where('id','in',$srIds)
                    ->update(['is_end'=>1,'update_time'=>time()]);
            }
            add_log('check', $id, $this->param,$this->title);
            Db::commit();
        }catch (\Exception $e){
            Db::rollback();
            return to_assign(1,'操作失败:'.$e->getMessage());
        }
        return to_assign(0,'操作成功');
    }
    /**
     * @return \json
     * @throws \think\db\exception\DbException
     * date:2024/3/21
     * 删除
     */
    public function delete()
    {
        if (request()->isDelete()) {
            $id = get_params("id");
            $status=Db::name($this->table)->where('id','in',$id)->column('status');
            if (in_array('2',$status)){
                return  to_assign(1, "有已确认数据，不能删除");
            }
            try {
                Db::name($this->table)->where('id','in',$id)->update(['status'=>-1,'deleted'=>time()]);
                Db::name('receipt_order_detail')->where('receipt_id','in',$id)->update(['status'=>-1,'deleted'=>time()]);
                add_log('delete', $id, request()->param(),$this->title);
            }catch (\Exception $e){
                return to_assign(1, "删除失败".$e->getMessage());
            }
            return to_assign(0, "删除成功");
        } else {
            return to_assign(1, "错误的请求");
        }
    }
    public function importData()
    {


        Db::startTrans();
        try {
            if (!isset($_FILES['file'])){
                throw new Exception('请选择上传文件');
            }
            //限制上传表格类型
            $fileExtendName = substr(strrchr($_FILES['file']["name"], '.'), 1);
            //application/vnd.ms-excel  为xls文件类型
            if ($fileExtendName != 'xlsx') {
                throw new Exception('必须为excel表格，且必须为xlsx格式！');
            }

            if (is_uploaded_file($_FILES['file']['tmp_name'])) {
                // 有Xls和Xlsx格式两种
//            $objReader = \IOFactory::createReader('Xlsx');
                $objReader = IOFactory::createReader('Xlsx');

                $filename = $_FILES['file']['tmp_name'];

                $objPHPExcel = $objReader->setReadDataOnly(true)->load($filename);  //$filename可以是上传的表格，或者是指定的表格

                $sheet = $objPHPExcel->getSheet(0);   //excel中的第一张sheet
                $highestRow = $sheet->getHighestRow();       // 取得总行数
                $importData = [];
                $pIds=[];
                $skTimes=[];
                $dIds=[];
                $moneys=[];
                //循环读取excel表格，整合成数组。如果是不指定key的二维，就用$data[i][j]表示。
                for ($j = 2; $j <= $highestRow; $j++) {
                    $purveyor_id=$objPHPExcel->getActiveSheet()->getCell("A" . $j)->getFormattedValue();
                    $purveyor_id=Db::name('purveyor')
                        ->where('dw_type',1)
                        ->where('status',1)->where('id',$purveyor_id)->value('id');
                    if (!$purveyor_id){
                        throw new Exception('供应商id有误,行:'.($j-1));
                    }
                    $time=$objPHPExcel->getActiveSheet()->getCell("B" . $j)->getFormattedValue();
                    $time=str_replace('/','-',$time);
                    if (!$time){
                        throw new Exception('时间有误,行:'.($j-1));
                    }
                    $dzdh=$objPHPExcel->getActiveSheet()->getCell("C" . $j)->getFormattedValue();
                    $dzId=Db::name('sale_reconcile')->where('status',2)
                        ->where('punter_id',$purveyor_id)->where('orderNum',$dzdh)->value('id');
                    if (!$dzId){
                        throw new Exception('对账单号有误,行:'.($j-1));
                    }
                    $price=(float)$objPHPExcel->getActiveSheet()->getCell("D" . $j)->getFormattedValue();
                    if (!$price){
                        throw new Exception('金额有误,行:'.($j-1));
                    }
                    $pIds[]=$purveyor_id;
                    $skTimes[]=$time;
                    $dIds[]=$dzId;
                    $moneys[]=$price;

                }
                $res=$this->createImData($pIds,$skTimes,$dIds,$moneys);
                if ($res['code']!=200){
                    throw new Exception($res['msg']);
                }
                $data=$res['data'];
                $rData=$data['rData'];
                $detail=$data['detail'];
                $receipt_id=Db::name($this->table)->insertGetId($rData);
                foreach ($detail as &$v){
                    $v['receipt_id']=$receipt_id;
                }
                Db::name('receipt_order_detail')->insertAll($detail);

                add_log('import', '', $data,$this->title.'->导入');
                Db::commit();
            }
        }catch (Exception $e){
            Db::rollback();
            return to_assign(1,'操作失败:'.$e->getMessage());
        }
        return to_assign();
    }

    public function createImData($pIds,$skTimes,$dIds,$moneys)
    {
        $pIds1=array_unique($pIds);
        if (count($pIds1)!=1){
            return ['code'=>400,'msg'=>'客户id不一致'];
        }
        $punId=$pIds1[0];
        $skTimes1=array_unique($skTimes);
        if (count($skTimes1)!=1){
            return ['code'=>400,'msg'=>'时间不一致'];
        }
        $time=$skTimes1[0];
        $rData=[
            'orderNum'=>orderNum('SKDH'),
            'punter_id'=>$punId,
            'orderDate'=>$time,
            'r_type'=>1,
            'status'=>1,
            'deleted'=>0,
            'create_time'=>time(),
            'update_time'=>time()
        ];
        $countPrice=0;
        $dData=[];
        foreach ($dIds as $k=>$v){
            $dkey='id_'.$v;
            if (isset($dData[$dkey])){
                $dData[$dkey]+=$moneys[$k];
            }else{
                $dData[$dkey]=$moneys[$k];
            }
        }
        $detail=[];
        foreach ($dData as $d=>$da){
            $idkeys=explode('_',$d);
            $dzid=$idkeys[1];
            $countPrice+=$da;
            $detail[]=[
                'sale_reconcile_id' =>$dzid,
                'punter_id'=>$punId,
                'money'=>$da,
                'rod_type'=>1,
                'status'=>1,
                'deleted'=>0,
                'create_time'=>time(),
                'update_time'=>time()
            ];
        }
        $rData['paymentPrice']=$countPrice;

        return ['code'=>200,'msg'=>'ok','data'=>['rData'=>$rData,'detail'=>$detail]];

    }

    public function exportData()
    {
        $where=session($this->sessionKey);
        $mStatus=['','草稿','已确认'];
        $list = Db::name($this->table)->alias('i')
            ->join('purveyor p','p.id=i.punter_id','left')
            ->join('admin a','a.id=i.checkUser','left')
            ->where($where)
            ->field('i.*,p.name as pName,a.name as username')
            ->select()
            ->each(function ($item,$index) use ($mStatus){
                $item['status']=$mStatus[$item['status']];
                return $item;
            });
        $title = [
//            'id' => 'ID',
            'orderNum' => '单据编码',
            'pName' => '供应商',
            'paymentPrice' => '付款金额',
            'username' => '付款人',
            'orderDate' => '单据日期',
            'status' => '状态',

        ];
        $name =$this->title;
        exportXlsData($name,$title,$list);
        exit();
    }
}